Subclassing API for mIRC (Final Version)
Written by NaquadaBomb  @ mirc-dll.com


Ever write a DLL with subclassing and have the problem of your DLL crashing mIRC? I have written this DLL package to assist mIRC DLL developers with using subclassing. One of the most useful abilities to have (when writing DLL's) is the ability to subclass a window's proc. The problem is Microsoft has really done a half ass job of implementing subclassing. This API addresses the problems people experience when subclassing. It provides a simple way for many DLL files to subclass the same windows in a harmonious way.

Here's how the whole thing works... I have written a DLL called SubclassMonitor.dll. This DLL needs to reside in the mIRC directory. The purpose of this DLL is to track multiple subclassings of the same window. And to disable all subclassing when processing the WM_CLOSE message.  The DLL also sends two message to mIRC's WndProc, SCWM_PRECLOSE and SCWM_CLOSECANCEL, you can use these events for undoing/redoing hooks if you are using them.

When any DLL that uses the Subclassing API is loaded, it makes a call to initialize the SubclassMonitor.dll if it isn't already initialized. SubclassMonitor.dll is loaded in to mIRC using LoadLibrary() rather than using mIRC to load the DLL. The reason SubclassMonitor.dll needs to load this way is because of a bug in mIRC versions <= 6.17 (which happens to be the current release, atm). I have talked with Khaled (mIRC's author) about this bug, and it should be fixed in 6.18 when released, click here for more details.

Please help me push DLL developers in making this a standard in the "mIRC DLL writing" community.

Here is a brief description of the functions you will need to use in your DLL. Please see the "Example DLL" project source for details.

The first thing to do is include "MonitorAccess.h" and add the MonitorAccess.lib to your project. Then in your DLL's LoadDLL() function, call InjectMonitor(hInstance). After that you simply use SafeSubclassWindow(), UnSubclassWindow(), NextWndProc(), and EnumSubclassing() as needed. Here are the function definitions...

HINSTANCE  InjectMonitor(HINSTANCE hInst, HWND hApp, LPSTR mData);
BOOL             SafeSubclassWindow(HINSTANCE hInst, HWND hwnd, WNDPROC lpfn);
BOOL             UnSubclassWindow(HINSTANCE hInst, HWND hwnd);
LRESULT       NextWndProc(HINSTANCE hInst, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT                 EnumSubclassing(HINSTANCE hInstDLL, HWND hwnd, ENUMSC enumfunc, LPARAM lParam);

Here's some additional source to get you started...

// HOW TO GET THE DLL's hInstance....
HINSTANCE    hInstance = NULL;
extern "C" int WINAPI _DllMainCRTStartup(HANDLE hInstDLL, DWORD, void*)
{
    hInstance = (HINSTANCE)hInstDLL;
    return 1;
}

// The bare minimum of a subclassed WNDPROC
LRESULT CALLBACK MyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg) {
            case WM_DESTROY:
                    UnSubclassWindow(hInstance, hwnd);
                    PostMessage(hwnd, uMsg, wParam, lParam);
                    return 0L;
            default:
                    break;
    }
    return NextWndProc(hInstance, hwnd, uMsg, wParam, lParam);
}